package timing.ukulele.web.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.TimeZone;

import static timing.ukulele.web.WebConstant.*;

/**
 * @author fengxici
 */
@Configuration
public class WebDataConvertConfig {

    @Value("${ukulele.web.ignore-null-field:false}")
    private Boolean ignoreNullField;

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Primary
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            //序列化成json时，将所有的Long变成string，以解决js中的精度丢失。
            SimpleModule long2StringModule = new SimpleModule("Long2StringModule");
            long2StringModule.addSerializer(Long.class, ToStringSerializer.instance);
            long2StringModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
            // 日期相关
            JavaTimeModule javaTimeModule = new JavaTimeModule();
            //序列化日期格式)
            javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATETIME_FORMATTER));
            javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
            javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER));
            //反序列化日期格式
            javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATETIME_FORMATTER));
            javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER));
            javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
            builder.modules(long2StringModule, javaTimeModule);
            if (ignoreNullField != null && ignoreNullField)
                builder.serializationInclusion(JsonInclude.Include.NON_NULL);
            builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
            // 日期序列化格式
            builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
        };
    }
}
